# -*- coding:utf-8 -*-
import uvicorn

from fastapi import FastAPI, HTTPException
from fastapi.exceptions import RequestValidationError
from fastapi.middleware.cors import CORSMiddleware
from starlette.middleware.sessions import SessionMiddleware
from fastapi.staticfiles import StaticFiles
from fastapi.openapi.docs import get_redoc_html, get_swagger_ui_html, get_swagger_ui_oauth2_redirect_html
from fastapi.openapi.utils import get_openapi
from tortoise.exceptions import OperationalError, DoesNotExist, IntegrityError, ValidationError
from api import router
from common.custom_logger import CustomLogger as Logger
from config import settings
from core import events
from core import exceptions
from core.base_middleware import BaseMiddleware

# from core.log_middleware import LogMiddleware


logger = Logger("weekly_main")

# FastAPI 应用
app = FastAPI(
    debug=settings.APP_DEBUG,
    docs_url=None,
    redoc_url=None
)


def custom_openapi():
    if app.openapi_schema:
        return app.openapi_schema
    openapi_schema = get_openapi(
        description=settings.DESCRIPTION,
        version=settings.VERSION,
        title=settings.PROJECT_NAME,
        routes=app.routes,
    )
    openapi_schema["info"]["x-logo"] = {"url": "/static/favicon.png"}
    app.openapi_schema = openapi_schema
    return app.openapi_schema


#
@app.get("/docs", include_in_schema=False)
async def custom_swagger_ui_html():
    return get_swagger_ui_html(
        openapi_url=app.openapi_url,
        title=app.title + " - Swagger UI",
        oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,
        swagger_js_url="/static/swagger-ui-bundle.js",
        swagger_css_url="/static/swagger-ui.css",
    )


@app.get(app.swagger_ui_oauth2_redirect_url, include_in_schema=False)
async def swagger_ui_redirect():
    return get_swagger_ui_oauth2_redirect_html()


@app.get("/redoc", include_in_schema=False)
async def redoc_html():
    return get_redoc_html(
        openapi_url=app.openapi_url,
        title=app.title + " - ReDoc",
        redoc_js_url="/static/redoc.standalone.js",
    )


# 中间件
# app.add_middleware(LogRequestMiddleware)
app.add_middleware(BaseMiddleware)
app.add_middleware(
    CORSMiddleware,
    allow_origins=settings.CORS_ORIGINS,
    allow_credentials=settings.CORS_ALLOW_CREDENTIALS,
    allow_methods=settings.CORS_ALLOW_METHODS,
    allow_headers=settings.CORS_ALLOW_HEADERS,
)
app.add_middleware(
    SessionMiddleware,
    secret_key=settings.SECRET_KEY,
    session_cookie=settings.SESSION_COOKIE,
    max_age=settings.SESSION_MAX_AGE
)

# 事件
app.add_event_handler("startup", events.startup(app))
app.add_event_handler("shutdown", events.stopping(app))

# 异常处理
app.add_exception_handler(HTTPException, exceptions.http_error_handler)
app.add_exception_handler(RequestValidationError, exceptions.http422_error_handler)
app.add_exception_handler(exceptions.UnicornException, exceptions.unicorn_exception_handler)
app.add_exception_handler(DoesNotExist, exceptions.mysql_does_not_exist)
app.add_exception_handler(IntegrityError, exceptions.mysql_integrity_error)
app.add_exception_handler(ValidationError, exceptions.mysql_validation_error)
app.add_exception_handler(OperationalError, exceptions.mysql_operational_error)

# 路由
app.include_router(router.router)
# 静态资源
app.mount('/static', StaticFiles(directory=settings.STATIC_DIR), name="static")

# 启动服务
if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000, log_config="logging.yaml")
